package services

import (
	"go-ddd-ecommerce/internal/application/dto"
	"go-ddd-ecommerce/internal/application/event_handlers"
	"go-ddd-ecommerce/internal/domain/events"
	"go-ddd-ecommerce/internal/domain/user"
)

type UserAppService struct {
	userRepo       user.Repository              // 用户仓储
	eventPublisher *events.DomainEventPublisher // 注入事件发布器
}

func NewUserAppService(
	userRepo user.Repository,
	eventPublisher *events.DomainEventPublisher,
) *UserAppService {
	service := &UserAppService{
		userRepo:       userRepo,
		eventPublisher: eventPublisher,
	}

	// 注册事件处理器
	service.registerEventHandlers()
	return service
}

// 注册事件处理器
func (s *UserAppService) registerEventHandlers() {
	// 注册会员处理器
	memberHandler := event_handlers.NewMemberHandler()
	s.eventPublisher.Subscribe("user.create", memberHandler)

	// 密码箱处理器
	passwordBoxHandler := event_handlers.NewPasswordBoxHandler()
	s.eventPublisher.Subscribe("user.password_update", passwordBoxHandler)
}

// 创建用户
func (s *UserAppService) CreateUser(cmd dto.CreateUserDTO) (dto.UserDataDTO, error) {
	u, err := user.NewUser(cmd.Username, cmd.Password)
	if err != nil {
		return dto.UserDataDTO{}, err
	}
	err = s.userRepo.Save(u)
	if err != nil {
		return dto.UserDataDTO{}, err
	}
	// 发布领域事件（在事务提交后发布，确保数据一致性）
	s.eventPublisher.PublishEvents(u)

	return dto.UserDataDTO{
		UserID:   u.ID,
		Username: u.Username,
		Balance:  u.Balance,
	}, nil
}

// 更新用户密码
func (s *UserAppService) UpdateUserPassword(cmd dto.UpdateUserPasswordDTO) error {
	// 1.查询用户
	u, err := s.userRepo.FindByID(cmd.UserID)
	if err != nil {
		return err
	}
	// 2.操作聚合根
	err = u.UpdatePassword(cmd.NewPassword)
	if err != nil {
		return err
	}
	// 3.持久化数据
	err = s.userRepo.Update(u)
	if err != nil {
		return err
	}
	// 发布领域事件（在事务提交后发布，确保数据一致性）
	s.eventPublisher.PublishEvents(u)
	return nil
}

// 获取用户信息
func (s *UserAppService) GetUserByID(cmd dto.GetUserByIDDTO) (dto.UserDataDTO, error) {
	us, err := s.userRepo.FindByID(cmd.UserID)
	if err != nil {
		return dto.UserDataDTO{}, err
	}

	return dto.UserDataDTO{
		UserID:   us.ID,
		Username: us.Username,
		Balance:  us.Balance,
	}, nil
}

// 增加用户余额
func (s *UserAppService) AddUserBalance(cmd dto.AddUserBalanceDTO) error {
	// 1.查询用户
	u, err := s.userRepo.FindByID(cmd.UserID)
	if err != nil {
		return err
	}
	// 2.操作聚合根
	err = u.AddBalance(cmd.Amount)
	if err != nil {
		return err
	}
	// 3.持久化数据
	err = s.userRepo.Update(u)
	if err != nil {
		return err
	}
	// 发布领域事件（在事务提交后发布，确保数据一致性）
	s.eventPublisher.PublishEvents(u)
	return nil
}
